"use strict";

var EXPORTED_SYMBOLS = ["iplusnewtab"]

Components.utils.import("resource://gre/modules/Services.jsm")

// The maximum number of results we want to retrieve from history.
//  const HISTORY_RESULTS_LIMIT = 100;

var iplusnewtab = {
    _cache : { },  // host  [  addr { count, from, last } ]

    //  a wrap of heroin:   "extensions.iplusnewtab.noticeDelta"
    getDelta : function(adefval)
    {
        var thour = Services.prefs.getIntPref("extensions.iplusnewtab.noticeDelta");
            if(thour > 24) thour = 24
            else if (thour < 0)
                    thour = adefval || 0;
        return (thour * 60 * 60 * 1000); // Number of milliseconds
    },

    //  newtab is calling
    //  in: host
    //  out: array of addresses
    //  condition: return copy versus link
    getStreet : function(ahost)
    {
        let vector = iplusnewtab._cache[ahost];
        if(vector && vector.length)
            return Array.slice(vector)

        if(ahost.indexOf("www.") === 0)
        {
           ahost = ahost.replace("www.", "");
           let thepos = ahost.indexOf(".");
           if((thepos.length > (thepos + 1)) && (thepos > 0))
           {
                vector = iplusnewtab._cache[ahost];
                if(vector && vector.length)
                    return Array.slice(vector)
           }
        }
        return [];
    },

    //  erase hostes are out of date:
    //  every.last < zero day
    erase   : function(adate)
    {
        var agglomerate = [ ];
        for(let thehost in iplusnewtab._cache)
        {
            let thentry = iplusnewtab._cache[thehost];
            let outdated = thentry.every(
                function (anobj) {
                    return (anobj.last < adate);
                } );

            if(outdated) {
//    dump("_dvk_dbg_, host is out of date:\t"); dump(thehost); dump("\n");
                agglomerate.push(thehost);
            }
        }

        for each (let thehost in agglomerate)
            delete iplusnewtab._cache[thehost];
    },

    //  insert address to host with upto day value
    insert : function(ahost, addr, adate)
    {
        if(!(ahost in iplusnewtab._cache))
            iplusnewtab._cache[ahost] = [ ];

        var findAlways = function(astreet)
        {
            let thobj = { "addr": addr, count: 0, from: null };
            for each (let theval in astreet)
                if(theval["addr"] == addr)
            {
                thobj = theval;
                ++thobj.count;
                break;
            }
    
            if(!(thobj.count)) astreet.push(thobj);
        
            return thobj;
        }

        var thentry = findAlways(iplusnewtab._cache[ahost]);
        if(thentry.count)
        {
            if(thentry.last < adate) thentry.last = adate;
        }
        else thentry["last"] = thentry.from = adate;
    },

    monitor :   //  dispatcher for one window handles cache
    {
        _window : { closed: true },

        //  event: deactivate
        setwin : function(awin)
        {
            if(!(this._window === awin) && !(awin.closed))
            try {
                awin.setTimeout( function(awin)
                    { iplusnewtab.monitor._window = awin }, 0, awin);
            }
            catch(err)
            {
                Components.utils.reportError(err)
            }
        },

        //  event: close, unload
        reset : function(awin)
        {
            if((!awin) || (this._window === awin))
                this._window = { closed: true }
        },

        //  event: pageshow
        host2cache : function (awin, ahost, addr, adate)
        {
            if(addr)
            try {
                var thewin = (this._window.closed) ? awin : this._window;
                thewin.setTimeout( function(ahost, addr, adate)
                       { iplusnewtab.insert(ahost, addr, adate) },
                                1, ahost, addr, (new Date()));
            }
            catch(err)  {
                this.reset(thewin)
                Components.utils.reportError(err)
            }
        },

        //  event: deactivate
        clearing : function (awin, adate)
        {
            if((Object.keys(iplusnewtab._cache).length) >> 2)
            try {
                var thewin = (this._window.closed) ? awin : this._window;
//    dump("_dvk_dbg_, clearing, up to:\t"); dump(adate); dump("\n");
                thewin.setTimeout( function(adate) { iplusnewtab.erase(adate) }, 1, adate );
            }
            catch(err)  {
                this.reset(thewin)
                Components.utils.reportError(err)
            }
        },

        //  event: activate
        verify : function(awin)
        {
            if(!(this._window === awin) && !(this._window.closed))
            try {
                var thewin = this._window;
                this.reset(null);
                thewin.setTimeout(
                        function(awin) { iplusnewtab.monitor._window = awin },
                            0, thewin);
            }
            catch(err)
            {
                Components.utils.reportError(err)
            }
        }
    }
}
